<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { Bell, Calendar, ChatDotRound, Warning, Delete, Close } from '@element-plus/icons-vue'
import { getUserMessages, readUserMessage, readAllUserMessages, deleteUserMessage } from '@/apis/user/userMessageAPI'
import { getAppointmentMessages } from '@/apis/user/userAppointmentAPI'
import type { Message } from '@/types/message'
import { messageTypeMap } from '@/types/message'
import { ElMessage } from 'element-plus'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:visible', 'read'])

// 消息列表
const messageList = ref<Message[]>([])
// 总消息数
const total = ref(0)
// 未读消息数
const unreadCount = ref(0)
// 当前页
const currentPage = ref(1)
// 每页数量
const pageSize = ref(10)
// 加载状态
const loading = ref(false)
// 当前选中的消息类型
const activeType = ref(0) // 0表示全部
// 当前选中的消息
const selectedMessage = ref<Message | null>(null)
// 是否显示消息详情
const showDetail = ref(false)

// 消息类型列表
const messageTypes = [
  { value: 0, label: '全部消息' },
  { value: 1, label: '系统消息' },
  { value: 2, label: '预约消息' },
  { value: 3, label: '问诊消息' },
  { value: 4, label: '紧急消息' }
]

// 获取消息图标
const getMessageIcon = (type: number) => {
  switch (type) {
    case 1:
      return Bell
    case 2:
      return Calendar
    case 3:
      return ChatDotRound
    case 4:
      return Warning
    default:
      return Bell
  }
}

// 获取消息列表
const fetchMessages = async () => {
  loading.value = true
  try {
    const params: any = {
      page: currentPage.value,
      pageSize: pageSize.value
    }

    // 如果选择了特定类型，添加类型过滤
    if (activeType.value !== 0) {
      params.type = activeType.value
    }

    // 获取普通消息
    const res = await getUserMessages(params)
    let messages: Message[] = []
    let totalCount = 0
    let unreadMessageCount = 0

    if (res.code === 200) {
      messages = res.data.list || []
      totalCount = res.data.total || 0
      unreadMessageCount = res.data.unreadCount || 0
    } else {
      ElMessage.error(res.message || '获取消息失败')
    }

    // 如果是查询全部消息或特定查询预约消息，则获取预约消息
    if (activeType.value === 0 || activeType.value === 2) {
      try {
        const appointmentParams = {
          page: currentPage.value,
          pageSize: pageSize.value,
          status: undefined // 预约消息API不支持按已读/未读筛选
        }

        const appointmentRes = await getAppointmentMessages(appointmentParams)
        if (appointmentRes.code === 200) {
          // 将预约消息添加到消息列表中
          const appointmentMessages = appointmentRes.data.list || []
          messages = [...messages, ...appointmentMessages]

          // 更新总数和未读数
          totalCount += appointmentRes.data.total || 0
          unreadMessageCount += appointmentRes.data.unreadCount || 0

          // 按时间排序（降序）
          messages.sort((a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime())

          // 分页处理
          const start = 0
          const end = pageSize.value
          messages = messages.slice(start, end)
        }
      } catch (appointmentError) {
        console.error('获取预约消息出错:', appointmentError)
      }
    }

    // 更新消息列表和计数
    messageList.value = messages
    total.value = totalCount
    unreadCount.value = unreadMessageCount
    emit('read', unreadCount.value)
  } catch (error) {
    console.error('获取消息列表出错:', error)
    ElMessage.error('获取消息列表失败')
  } finally {
    loading.value = false
  }
}

// 切换消息类型
const changeMessageType = (type: number) => {
  activeType.value = type
  currentPage.value = 1
  fetchMessages()
}

// 查看消息详情
const viewMessageDetail = async (message: Message) => {
  selectedMessage.value = message
  showDetail.value = true

  // 如果消息未读，标记为已读
  if (message.status === 0) {
    try {
      await readUserMessage(message.id)
      // 更新消息状态
      message.status = 1
      // 更新未读消息数
      if (unreadCount.value > 0) {
        unreadCount.value--
        emit('read', unreadCount.value)
      }
    } catch (error) {
      console.error('标记消息已读出错:', error)
    }
  }
}

// 返回消息列表
const backToList = () => {
  showDetail.value = false
  selectedMessage.value = null
}

// 全部标记为已读
const markAllAsRead = async () => {
  try {
    const res = await readAllUserMessages()
    if (res.code === 200) {
      ElMessage.success('全部标记为已读')
      // 更新消息状态
      messageList.value.forEach(msg => {
        msg.status = 1
      })
      // 更新未读消息数
      unreadCount.value = 0
      emit('read', 0)
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error) {
    console.error('标记全部已读出错:', error)
    ElMessage.error('操作失败')
  }
}

// 删除消息
const deleteMessage = async (message: Message, event?: Event) => {
  if (event) {
    event.stopPropagation()
  }

  try {
    const res = await deleteUserMessage(message.id)
    if (res.code === 200) {
      ElMessage.success('删除成功')
      // 从列表中移除
      messageList.value = messageList.value.filter(msg => msg.id !== message.id)
      // 如果当前查看的是这条消息，返回列表
      if (selectedMessage.value && selectedMessage.value.id === message.id) {
        backToList()
      }
      // 如果是未读消息，更新未读数
      if (message.status === 0 && unreadCount.value > 0) {
        unreadCount.value--
        emit('read', unreadCount.value)
      }
      // 更新总数
      if (total.value > 0) {
        total.value--
      }
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error) {
    console.error('删除消息出错:', error)
    ElMessage.error('删除失败')
  }
}

// 关闭弹窗
const closePopup = () => {
  emit('update:visible', false)
}

// 页码变化
const handleCurrentChange = (page: number) => {
  currentPage.value = page
  fetchMessages()
}

// 监听弹窗显示状态
const watchVisible = (val: boolean) => {
  if (val) {
    fetchMessages()
  } else {
    // 关闭弹窗时重置状态
    showDetail.value = false
    selectedMessage.value = null
  }
}

// 格式化时间
const formatTime = (time: string) => {
  if (!time) return ''
  const date = new Date(time)
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
}

// 监听visible属性变化
watch(() => props.visible, watchVisible)

// 组件挂载时获取消息列表
onMounted(() => {
  if (props.visible) {
    fetchMessages()
  }
})
</script>

<template>
  <el-dialog
    v-model="props.visible"
    title="消息中心"
    width="600px"
    :before-close="closePopup"
    class="message-popup"
  >
    <div class="message-container">
      <!-- 消息列表 -->
      <div v-if="!showDetail" class="message-list-container">
        <!-- 消息类型选择 -->
        <div class="message-type-tabs">
          <div
            v-for="type in messageTypes"
            :key="type.value"
            class="message-type-tab"
            :class="{ active: activeType === type.value }"
            @click="changeMessageType(type.value)"
          >
            {{ type.label }}
          </div>
          <div class="message-actions">
            <el-button type="primary" size="small" @click="markAllAsRead">全部已读</el-button>
          </div>
        </div>

        <!-- 消息列表 -->
        <el-scrollbar height="400px">
          <div v-loading="loading" class="message-list">
            <div v-if="messageList.length === 0" class="empty-message">
              <el-empty description="暂无消息" />
            </div>
            <div
              v-for="message in messageList"
              :key="message.id"
              class="message-item"
              :class="{ unread: message.status === 0 }"
              @click="viewMessageDetail(message)"
            >
              <div class="message-icon" :style="{ color: messageTypeMap[message.type]?.color }">
                <el-icon>
                  <component :is="getMessageIcon(message.type)" />
                </el-icon>
              </div>
              <div class="message-content">
                <div class="message-title">
                  <span>{{ message.title }}</span>
                  <span v-if="message.status === 0" class="unread-dot"></span>
                </div>
                <div class="message-brief">{{ message.content }}</div>
                <div class="message-time">{{ formatTime(message.createTime) }}</div>
              </div>
              <div class="message-actions">
                <el-button
                  type="danger"
                  size="small"
                  circle
                  @click.stop="deleteMessage(message, $event)"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </el-scrollbar>

        <!-- 分页 -->
        <div class="pagination-container">
          <el-pagination
            v-model:current-page="currentPage"
            :page-size="pageSize"
            layout="prev, pager, next"
            :total="total"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>

      <!-- 消息详情 -->
      <div v-else class="message-detail-container">
        <div class="detail-header">
          <el-button type="text" @click="backToList">
            <el-icon><arrow-left /></el-icon> 返回
          </el-button>
        </div>
        <div v-if="selectedMessage" class="detail-content">
          <div class="detail-title">
            <h3>{{ selectedMessage.title }}</h3>
            <div class="detail-meta">
              <span class="detail-type" :style="{ color: messageTypeMap[selectedMessage.type]?.color }">
                {{ messageTypeMap[selectedMessage.type]?.label }}
              </span>
              <span class="detail-time">{{ formatTime(selectedMessage.createTime) }}</span>
            </div>
          </div>
          <div class="detail-body">
            <p>{{ selectedMessage.content }}</p>
          </div>
          <div class="detail-footer">
            <el-button type="danger" @click="deleteMessage(selectedMessage)">删除消息</el-button>
          </div>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<style scoped lang="scss">
.message-popup {
  :deep(.el-dialog__header) {
    border-bottom: 1px solid #ebeef5;
    padding: 15px 20px;
  }

  :deep(.el-dialog__body) {
    padding: 0;
  }
}

.message-container {
  width: 100%;
}

.message-type-tabs {
  display: flex;
  border-bottom: 1px solid #ebeef5;
  padding: 0 15px;

  .message-type-tab {
    padding: 12px 15px;
    cursor: pointer;
    position: relative;
    font-size: 14px;

    &.active {
      color: var(--el-color-primary);
      font-weight: 500;

      &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 2px;
        background-color: var(--el-color-primary);
      }
    }
  }

  .message-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
  }
}

.message-list {
  min-height: 300px;

  .empty-message {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 300px;
  }

  .message-item {
    display: flex;
    padding: 15px 20px;
    border-bottom: 1px solid #ebeef5;
    cursor: pointer;
    transition: background-color 0.3s;

    &:hover {
      background-color: #f5f7fa;
    }

    &.unread {
      background-color: #f0f9ff;
    }

    .message-icon {
      margin-right: 15px;
      font-size: 20px;
      display: flex;
      align-items: center;
    }

    .message-content {
      flex: 1;
      overflow: hidden;

      .message-title {
        font-weight: 500;
        margin-bottom: 5px;
        display: flex;
        align-items: center;

        .unread-dot {
          width: 8px;
          height: 8px;
          border-radius: 50%;
          background-color: var(--el-color-danger);
          margin-left: 5px;
        }
      }

      .message-brief {
        color: #606266;
        font-size: 13px;
        margin-bottom: 5px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .message-time {
        color: #909399;
        font-size: 12px;
      }
    }

    .message-actions {
      display: flex;
      align-items: center;
    }
  }
}

.pagination-container {
  padding: 15px;
  display: flex;
  justify-content: center;
}

.message-detail-container {
  padding: 20px;

  .detail-header {
    margin-bottom: 20px;
  }

  .detail-content {
    .detail-title {
      margin-bottom: 20px;

      h3 {
        margin: 0 0 10px 0;
        font-size: 18px;
      }

      .detail-meta {
        display: flex;
        align-items: center;
        font-size: 13px;
        color: #909399;

        .detail-type {
          margin-right: 15px;
          font-weight: 500;
        }
      }
    }

    .detail-body {
      padding: 20px 0;
      border-top: 1px solid #ebeef5;
      border-bottom: 1px solid #ebeef5;
      min-height: 200px;

      p {
        line-height: 1.6;
        margin: 0;
      }
    }

    .detail-footer {
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style>
